#include "osd_keyboard.h"
#include "hard_pce.h"
#include "sound.h"

#ifdef DREAMCAST
#include "SDL_dreamcast.h"
#include "kos.h"
#endif



Uint16 read_input (Uint16 port);



Uint8 *key;
Int16 joy[J_MAX];

input_config config[16] = {
	{  // Config 0
		{
			{ 0, 0, 0, 0, 0, 0, { SDLK_UP, SDLK_DOWN, SDLK_LEFT, SDLK_RIGHT,
  				SDLK_SPACE, SDLK_LALT, SDLK_TAB, SDLK_RETURN, SDLK_c, SDLK_x,
  				-1, -1, -1, -1, -1, -1, -1, -1 } },
			{ 0, 0, 0, 0, 0, 0, { 0 } },
			{ 0, 0, 0, 0, 0, 0, { 0 } },
			{ 0, 0, 0, 0, 0, 0, { 0 } },
			{ 0, 0, 0, 0, 0, 0, { 0 } }
		}
	}
};

// info about the input config



UChar current_config;

// the number of the current config
char tmp_buf[100];

#define	JOY_A		0x01
#define	JOY_B		0x02
#define	JOY_SELECT	0x04
#define	JOY_RUN		0x08
#define	JOY_UP		0x10
#define	JOY_RIGHT	0x20
#define	JOY_DOWN	0x40
#define	JOY_LEFT	0x80

extern int UPeriod;


/* For joypad */
maple_device_t *joypad[4];


UInt16 read_input (UInt16 port)
{
  static char autoI_delay = 0, autoII_delay = 0;
  UInt16 tmp;

//  key = SDL_GetKeyState (NULL);

  for (tmp = J_PAD_START; tmp < J_MAX; tmp++)
    joy[tmp] = 0;

  tmp = 0;


    maple_device_t *cont;
    cont_state_t *state;

    cont = maple_enum_type(port, MAPLE_FUNC_CONTROLLER);
//	printf("algo\n");

    if(cont) {
        state = (cont_state_t *)maple_dev_status(cont);

//        if(!state)
//            return 0;

        if(state->buttons & CONT_START)
		    tmp |= JOY_RUN;

        if(state->buttons & CONT_Y)
		    tmp |= JOY_SELECT;

        if(state->buttons & CONT_DPAD_UP)
		    tmp |= JOY_UP;

        if(state->buttons & CONT_DPAD_DOWN)
		    tmp |= JOY_DOWN;

        if(state->buttons & CONT_DPAD_LEFT)
		    tmp |= JOY_LEFT;

        if(state->buttons & CONT_DPAD_RIGHT)
		    tmp |= JOY_RIGHT;

        if(state->buttons & CONT_A) 
			tmp |= JOY_A;

        if(state->buttons & CONT_B) 
			tmp |= JOY_B;

       
    }

// printf("%d\n",tmp);
  return tmp;
}



void
sdl_config_joypad_axis (short which, joymap axis, UInt16 * bad_axes,
			UInt16 num_axes)
{
  unsigned char t;
  boolean done = FALSE;

  while (1)
    {
      if (read (fileno (stdin), &t, 1) == -1)
	break;
    }

  while (!done)
    {
      time_t stime, ntime;
      int axes;

      if (read (fileno (stdin), &t, 1) == -1)
	{
	  if (errno != EAGAIN)
	    break;
	}
      else
	break;

      SDL_JoystickUpdate ();

      for (axes = num_axes - 1; axes >= 0; axes--)
	{
	  if (bad_axes[axes])
	    continue;

	  if (abs (SDL_JoystickGetAxis (joypad[which], axes)) > 16384)
	    {
	      printf
		("    -- Activity reported on axis %d;  Please release axis . . .\n",
		 axes);

	      config[current_config].individual_config[which].joy_mapping[axis] = axes;

	      done = 1;

	      stime = time (NULL);

	      while (abs (SDL_JoystickGetAxis (joypad[which], axes)) > 16384)
		{
		  SDL_JoystickUpdate ();
		  SDL_Delay (50);
		  ntime = time (NULL);

		  if ((ntime - stime) > 3)
		    {
		      bad_axes[axes] = 1;
		      done = 0;
		      printf
			("    ** Activity still reported on axis after 3 seconds, marking as invalid\n\n"
			 "    Please try another axis now . . .\n");
		      break;
		    }
		}
	      printf ("\n");
	    }
	}
    }

  while (1)
    {
      if (read (fileno (stdin), &t, 1) == -1)
	break;
    }
}


void
sdl_config_joypad_button (short which, joymap button, UInt16 * bad_buttons,
			  UInt16 num_buttons)
{
  unsigned char t;
  boolean done = FALSE;

  while (1)
    {
      if (read (fileno (stdin), &t, 1) == -1)
	break;
    }

  while (!done)
    {
      time_t stime, ntime;
      int buttons;

      if (read (fileno (stdin), &t, 1) == -1)
	{
	  if (errno != EAGAIN)
	    break;
	}
      else
	break;

      SDL_JoystickUpdate ();

      for (buttons = num_buttons - 1; buttons >= 0; buttons--)
	{
	  if (bad_buttons[buttons])
	    continue;

	  if (SDL_JoystickGetButton (joypad[which], buttons))
	    {
	      printf
		("    -- Button %d is pressed;  Please release button . . .\n",
		 buttons);

	      config[current_config].individual_config[which].joy_mapping[button] = buttons;

	      done = TRUE;

	      stime = time (NULL);

	      while (SDL_JoystickGetButton (joypad[which], buttons))
		{
		  SDL_JoystickUpdate ();
		  SDL_Delay (50);
		  ntime = time (NULL);

		  if ((ntime - stime) > 3)
		    {
		      bad_buttons[buttons] = 1;
		      done = FALSE;

		      printf
			("    ** Button %d still claiming to be pressed after 3 seconds, marked as invalid\n\n"
			 "    Please try another button now . . .\n",
			 buttons);
		      break;
		    }
		}
	      printf ("\n");
	    }
	}
    }

  while (1)
    {
      if (read (fileno (stdin), &t, 1) == -1)
	break;
    }
}


void
sdl_config_joypad (short which)
{
  int sa;
  UInt16 *bad_vals, n;

  printf ("    ^ We need to configure this joypad ^\n"
	  "    Press [ENTER] when ready to begin, [ENTER] can also be used to skip configuration steps.\n");
  getchar ();

#if !defined(WIN32)
  sa = fcntl (fileno (stdin), F_GETFL);
  fcntl (fileno (stdin), F_SETFL, O_NONBLOCK);
#endif

  n = SDL_JoystickNumAxes (joypad[which]);
  bad_vals = (UInt16 *) calloc (sizeof (UInt16), n);

  printf ("    - Press axis to use as x-plane (left/right)\n");
  sdl_config_joypad_axis (which, J_PXAXIS, bad_vals, n);

  printf ("    - Press axis to use as y-plane (up/down)\n");
  sdl_config_joypad_axis (which, J_PYAXIS, bad_vals, n);

  free (bad_vals);

  n = SDL_JoystickNumButtons (joypad[which]);
  bad_vals = (UInt16 *) calloc (sizeof (UInt16), n);

  printf ("    - Press button to use for 'RUN'\n");
  sdl_config_joypad_button (which, J_PRUN, bad_vals, n);

  printf ("    - Press button to use for 'SELECT'\n");
  sdl_config_joypad_button (which, J_PSELECT, bad_vals, n);

  printf
    ("    - Press button to use for 'I' (right-most button on pce pad)\n");
  sdl_config_joypad_button (which, J_PI, bad_vals, n);

  printf ("    - Press button to use for autofire toggle on 'I'\n");
  sdl_config_joypad_button (which, J_PAUTOI, bad_vals, n);

  printf
    ("    - Press button to use for 'II' (left-most button on pce pad)\n");
  sdl_config_joypad_button (which, J_PII, bad_vals, n);

  printf ("    - Press button to use for autofire toggle on 'II'\n");
  sdl_config_joypad_button (which, J_PAUTOII, bad_vals, n);

  free (bad_vals);

  printf ("                    Player %d\n"
	  "      *------------------------------------*\n"
	  "      |    %2d                    %2d   %2d   |\n"
	  "      |    __                  Turbo Turbo |\n"
	  "      |    ||                    __   __   |\n"
	  "      |  |====| %2d              (%2d) (%2d)  |\n"
	  "      |    ||      [%2d]  [%2d]    ~~   ~~   |\n"
	  "      |    ~~    Select  Run     II    I   |\n"
	  "      *------------------------------------*\n\n", which + 1,
	  config[current_config].individual_config[which].joy_mapping[J_PYAXIS],
	  config[current_config].individual_config[which].joy_mapping[J_PAUTOII],
	  config[current_config].individual_config[which].joy_mapping[J_PAUTOI],
	  config[current_config].individual_config[which].joy_mapping[J_PXAXIS],
	  config[current_config].individual_config[which].joy_mapping[J_PII],
	  config[current_config].individual_config[which].joy_mapping[J_PI],
	  config[current_config].individual_config[which].joy_mapping[J_PSELECT],
	  config[current_config].individual_config[which].joy_mapping[J_PRUN]);

#if !defined(WIN32)
  fcntl (fileno (stdin), F_SETFL, sa);
#endif
}


int input_enum(){
	int numdevs;
	int i;

	numdevs = 0;
	//Update KOS Maple
	int n = maple_enum_count();
	for (i=0;i<n;i++){
		maple_device_t *cont = maple_enum_type(i, MAPLE_FUNC_CONTROLLER);
		if (cont){
			//SYS_Joystick_addr[numdevs] = cont;
			numdevs++;
		}
	}
	return numdevs;
}


void init_joypads(void)
{

	
 /* int n;
  int joypad_number = SDL_NumJoysticks();

	printf("Found %d joypad%s\n", joypad_number, joypad_number > 1 ? "s" : "");

  for (n = 0; n < joypad_number; n++)
    {

      if ((joypad[n] = SDL_JoystickOpen(n)) == NULL)
	{
	  printf ("SDL could not open system joystick device %d (%s)\n", n, SDL_GetError ());
	  continue;
	}

      printf (" * PCE joypad %d: %s, %d axes, %d buttons\n", n + 1,
	      SDL_JoystickName (n),
	      SDL_JoystickNumAxes (joypad[n]),
	      SDL_JoystickNumButtons (joypad[n]));


    }*/
}


int osd_keyboard (void)
{



  /* 
   * while (key[KEY_PAUSE])
   * pause ();
   */

  
  io.JOY[0] = read_input (0);
  io.JOY[1] = read_input (1);
  io.JOY[2] = read_input (2);
  io.JOY[3] = read_input (3);
  io.JOY[4] = read_input (4);

  return 0;
}


int
osd_init_input (void)
{


	init_joypads ();


  return 0;
}

void
osd_shutdown_input ()
{
}




